﻿
/*
 *  当两艘舟船在非架桥点 桥连接线上，施行两条船组合时，
 *  我们动态的判定，两条船组合变形成 新的九桥接或者十桥接船
*/

using System.Collections.Generic;
using UnityEngine;
using Framework.Common;
using Framework.Entity;
using BridgeShips;
using Framework.FSM;
namespace BridgeShips {
    public class CombinedDeformationManager : Singleton<CombinedDeformationManager> {

        // Only surport tow ships to Combined or Defromation.

        public class PosForward {
            public Vector2 posFir = Vector3.zero;
            public Vector2 posSec = Vector3.zero;
            public Vector3 forward = Vector3.zero;
        }

        public SortedDictionary<uint, ShipProperty> CombineDeforDic = new SortedDictionary<uint, ShipProperty>();

        // Use this for initialization
        void Start() {

        }

        public ShipProperty Get( uint id ) {
            ShipProperty combineShip = null;
            if (CombineDeforDic.ContainsKey( id )) {
                CombineDeforDic.TryGetValue( id, out combineShip );
                return combineShip;
            }
            return combineShip;
        }

        public void GenCompineDeformation(uint first, uint second) {
            ShipProperty sp = new ShipProperty();
            sp.Id1 = first;
            sp.Id2 = second;
            sp.Type = GetCompineDefType(  first,  second );
            uint newID = ShipsDictionary.Instance.HashCode( first , second );
            sp.Id = newID;
            ShipsDictionary.Instance.shipDic.Add( newID, sp );

            MakePartsShipsValide( first , second ,sp);

            uint[] arrID = new uint[2];
            arrID[0] = ((first < second) ? first : second);
            arrID[1] = ((first > second) ? first : second);
            GameEntry.Instance.VirtualRManager.SwapModelAndSort( arrID , (int)sp.Type );
        }

        private void GetPartsShip( uint shipID, PosForward pfw ,int index) {
            ShipProperty combineFirstShip = null;
            if (CombineDeforDic.ContainsKey( shipID )) {
                CombineDeforDic.TryGetValue( shipID, out combineFirstShip );
                combineFirstShip.Valid = false;
            }
            else {
                if (ShipsDictionary.Instance.shipDic.ContainsKey(shipID))
                {
                    ShipsDictionary.Instance.shipDic[shipID].Valid = false;
                    CombineDeforDic.Add(shipID, ShipsDictionary.Instance.shipDic[shipID]);
                }
            }

            IEntity entity = GameEntry.Instance.EntityManager.Get( shipID );
            if (entity != null) {
                if (index == 1) {
                    pfw.posFir.x = entity.Position().x;
                    pfw.posFir.y = entity.Position().z;
                }
                else if (index == 2) {
                    pfw.posSec.x = entity.Position().x;
                    pfw.posSec.y = entity.Position().z;
                }
                pfw.forward = entity.Get().transform.forward;
            }
        }

        private void MakePartsShipsValide( uint firID, uint secID, ShipProperty sp ) {

            ShipsDictionary.Instance.shipDic[firID].Id1 = (uint)((firID < secID) ? firID : secID);
            ShipsDictionary.Instance.shipDic[firID].Id2 = (uint)((firID > secID) ? firID : secID);

            ShipsDictionary.Instance.shipDic[secID].Id1 = (uint)((firID < secID) ? firID : secID);
            ShipsDictionary.Instance.shipDic[secID].Id2 = (uint)((firID > secID) ? firID : secID);

            PosForward pfw = new PosForward();
            GetPartsShip( firID , pfw ,1);
            GetPartsShip( secID, pfw ,2);

            sp.FirstPosition = new Vector3( (pfw.posFir.x  + pfw.posSec.x) * 0.5f, 7.0f,(pfw.posFir.y  + pfw.posSec.y) * 0.5f );
            sp.SecondPosition = sp.FirstPosition;
            IEntity entity = GameEntry.Instance.EntityManager.Get(firID);
            if (entity != null)
            {
                sp.CurrentHeading = entity.Get().transform.localRotation;
            }
               
        }

        public ShipProperty.ShipsType GetCompineDefType( uint first, uint second ) {
            ShipProperty sp1, sp2;
            bool result1 = ShipsDictionary.Instance.shipDic.TryGetValue( first , out sp1);
            bool result2 = ShipsDictionary.Instance.shipDic.TryGetValue( first, out sp2 );
            if (result1 && result2)
                return (ShipProperty.ShipsType)( (int)sp1.Type + (int)sp2.Type + 2);
            return ShipProperty.ShipsType.None;
        }

       public void DoLastThing(uint firID, uint secID,bool disable) {
            IEntity ef = GameEntry.Instance.EntityManager.Get( firID );
            if(ef != null) {
                GameEntry.Instance.FsmManager.DestroyFsm( ef.Get().name );
                GameEntry.Instance.VehicleEntityManager.RemoveVehicleOperator( ef.Get().name );
                ef.GetAI().Settings.enabled = disable;
                ef.GetAI().enabled = disable;
                ef.Get().transform.GetComponentInChildren<MeshRenderer>().enabled = disable;
                //ef.Get().transform.parent.gameObject.SetActive( disable );
            }
            IEntity es = GameEntry.Instance.EntityManager.Get( secID );
            if (es != null) {
                GameEntry.Instance.FsmManager.DestroyFsm( es.Get().name );
                GameEntry.Instance.VehicleEntityManager.RemoveVehicleOperator( es.Get().name );
                es.GetAI().Settings.enabled = disable;
                es.GetAI().enabled = disable;
                es.Get().transform.GetComponentInChildren<MeshRenderer>().enabled = disable;
                //es.Get().transform.parent.gameObject.SetActive( disable );
            }
        }

        public bool IsContainCombinedID( uint shipID ) {
            if (CombineDeforDic.ContainsKey( shipID )) {
                return true;
            }
            return false;
        }
        public Vector3 GetCombineShipPosition(uint shipID ) {
            if (IsContainCombinedID( shipID )) {
                IEntity e1 = GameEntry.Instance.EntityManager.Get( (uint)CombineDeforDic[shipID].Id1 );
                IEntity e2 = GameEntry.Instance.EntityManager.Get( (uint)CombineDeforDic[shipID].Id2 );
                if (e1 != null && e2 != null) {
                    Vector3 combinePos = (e1.Get().transform.position + e2.Get().transform.position) * 0.5f;
                    combinePos.y = ShipsDictionary.Instance.HashCode( (uint)CombineDeforDic[shipID].Id1, (uint)CombineDeforDic[shipID].Id2 );
                    if (ShipsDictionary.Instance.shipDic.ContainsKey( (uint)combinePos.y ) == false)
                        return Vector3.zero;

                    return combinePos;
                }
            }
            return Vector3.zero;
        }

        // Update is called once per frame
        public void Update() {
            foreach (var item in CombineDeforDic)
            {
                IEntity entity = GameEntry.Instance.EntityManager.Get(item.Key);
                if (entity == null) continue;
                if (item.Value.Valid == false)
                {
                    if ( entity.Get().activeSelf)
                    {
                        entity.Get().GetComponentInChildren<MeshRenderer>().enabled = item.Value.Valid;
                        entity.Get().SetActive(item.Value.Valid);
                    }
                }
                else if (entity.Get().activeSelf == false)
                {
                    entity.Get().GetComponentInChildren<MeshRenderer>().enabled = item.Value.Valid;
                    entity.Get().SetActive(item.Value.Valid);
                }
            }
        }
    }
}